package com.tich.blog.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tich.blog.domain.dto.BlogDTO;
import com.tich.blog.domain.dto.BlogRecommendDTO;
import com.tich.blog.domain.dto.FavoriteBlogDTO;
import com.tich.blog.domain.entity.Blog;
import com.tich.blog.domain.vo.BlogRecommendVO;
import com.tich.blog.domain.vo.BlogVO;
import com.tich.blog.domain.vo.BlogsVO;
import com.tich.blog.domain.vo.FavoriteCursorVO;
import com.tich.blog.mapper.BlogCommentsMapper;
import com.tich.blog.mapper.BlogMapper;
import com.tich.blog.service.IBlogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tich.blog.service.IFavoriteBlogService;
import com.tich.constant.BlogConstant;
import com.tich.constant.RabbitMqConstant;
import com.tich.constant.SQLConstant;
import com.tich.context.UserContext;
import com.tich.exception.IllegalArgumentExceptionException;
import com.tich.utils.IdGeneratorUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Array;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 王志宇
 * @since 2025-05-14
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService {
    @Autowired
    IFavoriteBlogService favoriteBlogService;

    @Override
    public void saveBlog(BlogDTO blogDTO) {
        // 校验图片列表非空（保留原有逻辑）
        if (blogDTO.getImages_urls().isEmpty()) {
            throw new IllegalArgumentException(BlogConstant.IMAGE_NULL);
        }

        // 将 List<String> 转为逗号分隔的字符串（如："url1,url2,url3"）
        String imagesStr = String.join(",", blogDTO.getImages_urls());

        // 构建 Blog 实体，手动设置 images 字段
        Blog blog = Blog.builder()
                .id(IdGeneratorUtil.getInstance().nextId())
                .userId(UserContext.getCurrentId())
                .title(blogDTO.getTitle())
                .images(imagesStr) // 存入逗号分隔的字符串
                .content(blogDTO.getContent())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

        // 保存到数据库
        save(blog);
    }

    @Autowired
    RabbitTemplate rabbitTemplate;
    /**
     *根据id查询blog
     * @param id
     * @return
     */
    @Override
    public BlogVO queryBlogById(Long id) {
        //TODO 查询redis

        Blog blog = getById(id);
        BlogVO blogVO = BlogVO.builder()
                .comments(blog.getComments())
                .id(blog.getId())
                .title(blog.getTitle())
                .liked(blog.getLiked())
                .userId(blog.getUserId())
                .createTime(blog.getCreateTime())
                .imagesUrls(convertImageUrlsToString(blog.getImages()))
                .build();

        //TODO 存入redis
        return blogVO;
    }

    /**
     *展示最新发布的帖子
     * @param blogRecommendDTO
     * @return
     */
    @Override
    public BlogRecommendVO queryBlogs(@NotNull BlogRecommendDTO blogRecommendDTO) {
        LambdaQueryWrapper<Blog> queryWrapper = Wrappers.lambdaQuery(Blog.class);

        if (blogRecommendDTO.getCursor() != null) {
            queryWrapper.lt(Blog::getUpdateTime, blogRecommendDTO.getCursor());
        }

        queryWrapper.orderByDesc(Blog::getUpdateTime)
                .last(SQLConstant.LIMIT + blogRecommendDTO.getCount());

        List<Blog> blogs = getBaseMapper().selectList(queryWrapper);

        List<BlogsVO> blogsVOList = new ArrayList<>();
        for (Blog blog : blogs) {
            //只要第一张照片
            String firstImageUrl = blog.getImages().isEmpty()
                    ? ""
                    : convertImageUrlsToString(blog.getImages()).get(0); // 注意：若 images 为空，这里也可能有问题！
            BlogsVO blogsVO = BlogsVO.builder()
                    .id(blog.getId())
                    .title(blog.getTitle())
                    .images(firstImageUrl)
                    .build();
            blogsVOList.add(blogsVO);
        }

        //处理空列表
        LocalDateTime cursor = null;
        if (!blogs.isEmpty()) { // 先判断列表非空
            cursor = blogs.get(blogs.size() - 1).getCreateTime(); // 安全访问最后一个元素
        }

        return BlogRecommendVO.builder()
                .blogsVO(blogsVOList)
                .cursor(cursor) // 空列表时 cursor 为 null
                .build();
    }

    /**
     *删除帖子
     * @param id
     */
    @Override
    public void deleteBlogById(Long id) {
        //查询帖子
        Blog blog = getById(id);
        //不存在直接返回
        if (blog == null) {
            return;
        }
        removeById(id);
        //存入删除表
        try {
            rabbitTemplate.convertAndSend(RabbitMqConstant.BLOG_DIRECT, RabbitMqConstant.BLOG_DELETE_KEY,blog);
        }catch (Exception e){
            throw new IllegalArgumentException(e);
        }
    }

    /**
     *
     * @param favoriteBlogDTO
     * @return
     */
    @Override
    public BlogRecommendVO getFavoriteBlogs(FavoriteBlogDTO favoriteBlogDTO) {
        //TODO 查询reids

        //调用favoriteBlogService,查出blogId
        FavoriteCursorVO favoriteCursorVO = favoriteBlogService.getFavoriteBlogIds(favoriteBlogDTO);
        List<Long> ids = favoriteCursorVO.getIds();

        if (ids == null || ids.isEmpty()) {
            return BlogRecommendVO.builder()
                    .blogsVO(Collections.emptyList())
                    .cursor(null)
                    .build();
        }

        // 查询数据库
        LambdaQueryWrapper<Blog> queryWrapper = Wrappers.lambdaQuery(Blog.class);
        queryWrapper.in(Blog::getId, ids); // 通过ID集合查询博客


        // 按ID在集合中的顺序排序（可选，保持与收藏顺序一致）
        List<Blog> unordered = getBaseMapper().selectList(queryWrapper);
        Map<Long, Blog> blogMap = unordered.stream()
                .collect(Collectors.toMap(Blog::getId, blog -> blog));
        List<Blog> blogs = ids.stream()
                .map(blogMap::get)
                .filter(Objects::nonNull)
                .toList();

        // 转换
        List<BlogsVO> blogsVOList = new ArrayList<>();
        for (Blog blog : blogs) {
            String firstImageUrl = blog.getImages().isEmpty()
                    ? ""
                    : convertImageUrlsToString(blog.getImages()).get(0);
            BlogsVO blogsVO = BlogsVO.builder()
                    .id(blog.getId())
                    .title(blog.getTitle())
                    .images(firstImageUrl)
                    .build();
            blogsVOList.add(blogsVO);
        }

        // 处理空列表
        LocalDateTime cursor = null;
        if (!blogs.isEmpty()) {
            cursor = blogs.get(blogs.size() - 1).getCreateTime();
        }

        return BlogRecommendVO.builder()
                .blogsVO(blogsVOList)
                .cursor(favoriteCursorVO.getCursor())
                .build();
    }


    /**
     * 将逗号分隔的images转为List<string>的工具方法
     * @param images
     * @return
     */
    public List<String> convertImageUrlsToString(String images) {
        if (images == null || images.isEmpty()) {
            return List.of();
        }

        return Arrays.stream(images.split(","))
                .filter(str -> !str.isEmpty())
                .collect(Collectors.toList());
    }
}
